package obecto.utility
{
	import flash.system.ApplicationDomain;
	import flash.utils.Dictionary;
	import flash.utils.describeType;
	import flash.utils.getQualifiedClassName;
	
	public class ReflectionUtility
	{
		private static var descriptionsByClassName : Dictionary = new Dictionary(true);
		
		public static function getDescriptionXml(instance : Object) : XML
		{
			var className : String = getQualifiedClassName(instance);
			var result : XML = XML(descriptionsByClassName[className]);
			if (result.toString().length == 0)
			{
				var domain : ApplicationDomain = ApplicationDomain.currentDomain; 
				var type : Class = domain.getDefinition(className) as Class;
				result = describeType(type);
				
				descriptionsByClassName[className] = result;
			}
			return result;
		}
		
		public static function checkAccessor(accessor : String, instance : Object) : Boolean
		{
			var description : XML = getDescriptionXml(instance);
			var result : Boolean = descriptionContainsAccessor(accessor, description);
			return result;
		}
		
		public static function descriptionContainsAccessor(accessor : String, description : XML) : Boolean
		{
			var accessorXML : Object = description.factory.accessor.(@name == accessor);
			return (accessorXML as XMLList).length() != 0;
		}
		
		public static function getNonstaticReadWriteAccessors(instance : Object) : Array 
		{
			var result : Array = [];
			var description : XML = getDescriptionXml(instance);
			for each (var accessor : XML in description.factory.accessor.(@access == "readwrite")) 
			{
				result.push(accessor.@name);
			}
			return result;
		}
		
		public static function getNonstaticProperties(instance : Object) : Array
		{
			var result : Array = [];
			var description : XML = getDescriptionXml(instance);
			for each (var variable : XML in description.factory.variable) 
			{
				result.push(variable.@name);
			}
			return result;
		}

	}
}